<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>拦截器</title>
	<!--<script src="https://cdn.bootcdn.net/ajax/libs/axios/1.7.8/axios.min.js"></script>-->
</head>
<body>
	<script>
		// 构造函数
		function Axios(config){
			// 初始化
			this.config = config;// 为了创建 default 默认属性
			this.interceptors = {
				request:new interceptorManager(),
				response:new interceptorManager()
			}
		}
		// 发送请求 难点与重点
		Axios.prototype.request = function(config){
			// 创建一个 promise 对象
			let promise = Promise.resolve(config)
			// 创建一个数组
			let chains = [dispatchRequest,undefined]// undefined 占位
			// 处理拦截器
			// 请求拦截器 将请求拦截器的回调 压入到 chains 的前面 request.handles = []
			this.interceptors.request.handlers.forEach(item=>{
				chains.unshift(item.fulfilled,item.rejected)
			})
			// 响应拦截器
			this.interceptors.response.handlers.forEach(item=>{
				chains.push(item.fulfilled,item.rejected)
			})
			
			//遍历
			while(chains.length>0){
				promise = promise.then(chains.shift(),chains.shift())
			}
			return promise
		}

		// 发送请求
		function dispatchRequest(config){
			//返回一个promise 对象
			return new Promise((resolve,reject)=>{
				resolve({
					status:200,
					statusText:'OK'
				});
			})
		}

		// 创建实例
		let context = new Axios({});
		// 创建axios函数
		let axios = Axios.prototype.request.bind(context)
		// 将 context 属性 config interceptors 添加到axios函数对象上
		Object.keys(context).forEach(key=>{
			axios[key] = context[key]
		})

		// 拦截器管理器构造函数
		function interceptorManager(){
			this.handlers = [];
		}
		interceptorManager.prototype.use = function(fulfilled, rejected){
			this.handlers.push({
				fulfilled,
				rejected
			})
		}

		// 以下为功能测试代码
		// 设置请求拦截器 config 配置对象
		axios.interceptors.request.use(function one(config) {
			console.log('请求拦截器 成功 - 1号');
			// 修改 config 中的参数
			return config;
			//throw '参数出了问题'
		}, function one(error) {
			console.log('请求拦截器 失败 - 1号');
			return Promise.reject(error);
		})

		axios.interceptors.request.use(function two(config) {
			console.log('请求拦截器 成功 - 2号');
			// 修改 config 中的参数
			return config;
		}, function two(error) {
			console.log('请求拦截器 失败 - 2号');
			return Promise.reject(error);
		})

		// 设置响应拦截器
		axios.interceptors.response.use(function (response) {
			console.log('响应拦截器 成功 - 1号');
			return response
			//return response;
		}, function (error) {
			console.log('响应拦截器 失败 - 1号');
			return Promise.reject(error);
		})

		axios.interceptors.response.use(function (response) {
			console.log('响应拦截器 成功 - 2号');
			return response;
		}, function (error) {
			console.log('响应拦截器 失败 - 2号');
			return Promise.reject(error);
		})

		//console.dir(axios);

		// 发送请求
		axios({
            method: 'GET',
            url: 'http://localhost:3000/posts'
        }).then(response => {
            console.log(response);
        });
	</script>
</body>
</html>